import datetime
from collections import defaultdict
from datetime import datetime, timedelta

import numpy as np


# import datetime
# import logging
# 定义一个 main 函数，传入 params 参数。params 中包含了节点配置的输入变量。
# 需要定义一个字典作为输出变量
# 引用节点定义的变量：params['变量名']
# 运行环境 Python3；预置 Package：NumPy

# 风险评估引擎
def main(params):
    # 加载危机数据
    crisis_data = load_crisis_data()

    # 评估响应速度
    response_speed = evaluate_response_speed(crisis_data)

    # 评估沟通透明度
    transparency = evaluate_transparency(crisis_data)

    # 评估品牌形象保护
    image_protection = evaluate_brand_image_protection(crisis_data)

    # 综合得分
    comprehensive_score = generate_comprehensive_score(response_speed, transparency, image_protection)

    # 评估结果
    evaluation_results = generate_evaluation_report(response_speed, transparency, image_protection, comprehensive_score)

    # 创建一个字典作为输出变量
    output_object = {
        "brand_name": params['brand'],
        # "crisis_data": crisis_data,
        "response_speed": response_speed,
        "transparency": transparency,
        "image_protection": image_protection,
        "comprehensive_score": comprehensive_score,
        "evaluation_results": evaluation_results
    }

    # 返回输出字典类型变量 output_object，包含代码节点所需的输出数据
    return output_object


def load_crisis_data(days=30):
    # 特斯拉的危机关键词
    crisis_keywords = ['刹车失灵', '自动驾驶事故', '电池起火', '突然降价', '维权', '质量问题', '缺陷', '投诉', '不满',
                       '失败', '道歉', '召回']
    tesla_crisis_keywords = ['自动驾驶', '刹车失灵', '电池起火', '车门故障', '系统故障', '安全隐患',
                             '突然加速', '碰撞事故', '制动系统', '车联网漏洞', '降级软件', '电池衰减']
    crisis_keywords.extend(tesla_crisis_keywords)

    # 初始化日期和数据
    end_date = datetime.now().date()
    start_date = end_date - timedelta(days=days)
    current_date = start_date

    mock_data = []

    # 为每一天生成数据
    while current_date <= end_date:
        # 确定当天是否发生危机（20%的概率）
        is_crisis_day = np.random.random() < 0.2

        # 生成每日数据点（2-10条）
        daily_points = np.random.randint(2, 10)

        for _ in range(daily_points):
            # 70%的内容是社交媒体，20%是新闻，10%是官方声明
            data_type = np.random.choice(['social', 'news', 'official'], p=[0.7, 0.2, 0.1])

            # 如果是危机日，80%的内容与危机相关
            is_crisis_related = np.random.random() < 0.8 if is_crisis_day else np.random.random() < 0.1

            # 生成情感得分（危机相关的内容更倾向于负面）
            sentiment_score = np.random.normal(-0.7, 0.3) if is_crisis_related else np.random.normal(0.3, 0.3)
            sentiment_score = max(-1.0, min(1.0, sentiment_score))  # 限制在[-1,1]范围内

            # 生成内容标题和正文
            if data_type == 'social':
                if is_crisis_related:
                    title = f"用户抱怨特斯拉的{np.random.choice(crisis_keywords)}问题"
                    content = f"这是一条关于特斯拉的{np.random.choice(crisis_keywords)}问题的社交媒体抱怨。用户表示非常不满，希望得到解决。"
                else:
                    title = f"用户分享特斯拉使用体验"
                    content = f"这是一条关于特斯拉的普通社交媒体内容。用户分享了产品使用体验。"

                source = np.random.choice(['微博用户', '知乎用户', '小红书用户', '抖音用户'])
                platform = np.random.choice(['微博', '知乎', '小红书', '抖音'])
                engagement = np.random.randint(10, 500)

            elif data_type == 'news':
                if is_crisis_related:
                    title = f"媒体报道特斯拉面临{np.random.choice(crisis_keywords)}危机"
                    content = f"这是一篇关于特斯拉面临{np.random.choice(crisis_keywords)}危机的新闻报道。报道详细描述了事件经过和消费者反应。"
                else:
                    title = f"媒体报道特斯拉最新动态"
                    content = f"这是一篇关于特斯拉的普通新闻报道。报道介绍了品牌的最新动态和市场表现。"

                source = np.random.choice(['新华网', '人民日报', '南方周末', '财经网', '科技日报'])
                platform = '新闻媒体'
                engagement = np.random.randint(500, 5000)

            else:  # official
                statement_title = f"特斯拉官方声明：关于'近期问题'的说明"
                statement_content = f"这是特斯拉关于'近期问题'的官方声明。我们重视每一位用户的反馈，正在积极解决问题。我们承诺将{np.random.choice(['改进产品', '优化服务', '加强质量控制', '提供补偿'])}。"

                # 官方声明一般是积极的响应
                response_tone = np.random.uniform(0.1, 0.9) if is_crisis_related else sentiment_score

                source = f"特斯拉官方"
                platform = np.random.choice(['官方网站', '官方微博'])
                engagement = np.random.randint(1000, 5000)
                title = statement_title
                content = statement_content
                sentiment_score = response_tone

            # 组织数据
            published_time = datetime.combine(
                current_date,
                datetime.min.time()
            ) + timedelta(hours=np.random.randint(9, 23), minutes=np.random.randint(0, 59))

            mock_data.append({
                'data_type': data_type,
                'title': title,
                'content': content,
                'source': source,
                'published_time': published_time,
                'date': current_date,
                'url': f"https://example.com/{data_type}/{np.random.randint(1000, 9999)}",
                'platform': platform,
                'engagement': engagement,
                'sentiment_score': sentiment_score,
                'crisis_related': 1 if is_crisis_related else 0,
                'crisis_keyword': np.random.choice(crisis_keywords) if is_crisis_related else "",
                'brand_name': '特斯拉',
                'processed_time': datetime.now()
            })

        # 移至下一天
        current_date += timedelta(days=1)

    # 保存为类属性并返回
    crisis_data = mock_data

    return mock_data


def _preprocess_data(crisis_data):
    """
    预处理数据

    Returns:
        预处理后的数据
    """
    if not crisis_data:
        return []

    # 按日期排序
    crisis_data.sort(key=lambda x: x['published_time'])

    return crisis_data


def evaluate_response_speed(crisis_data):
    """
    评估响应速度

    Returns:
        响应速度评分 (1-5)
    """
    if not crisis_data:
        return 0

    # 预处理数据
    _preprocess_data(crisis_data)

    # 只关注危机相关的数据
    crisis_items = [item for item in crisis_data if item['crisis_related'] == 1]

    if not crisis_items:
        return 3  # 返回中等分数

    # 按平台分组
    by_platform = defaultdict(list)
    for item in crisis_items:
        by_platform[item['data_type']].append(item)

    # 计算从社交媒体/新闻报道到官方回应的时间间隔
    if 'official' not in by_platform:
        response_speed_score = 1.5
        return response_speed_score

    # 获取第一条危机相关内容和第一条官方回应
    crisis_start = min([item['published_time'] for item in crisis_items
                        if item['data_type'] in ['social', 'news']],
                       default=None)

    if not crisis_start:
        response_speed_score = 3
        return response_speed_score

    first_response = min([item['published_time'] for item in by_platform['official']],
                         default=None)

    if not first_response:
        response_speed_score = 1.5
        return response_speed_score

    # 计算响应时间（小时）
    response_time = (first_response - crisis_start).total_seconds() / 3600

    # 根据响应时间评分
    if response_time <= 2:
        score = 5.0  # 极快响应（2小时内）
    elif response_time <= 6:
        score = 4.0  # 快速响应（6小时内）
    elif response_time <= 12:
        score = 3.0  # 较好响应（12小时内）
    elif response_time <= 24:
        score = 2.0  # 一般响应（24小时内）
    else:
        score = 1.0  # 缓慢响应（24小时以上）

    return score


def evaluate_transparency(crisis_data):
    """
    评估沟通透明度

    Returns:
        透明度评分 (1-5)
    """
    if not crisis_data:
        return 0

    # 只关注官方声明
    official_statements = [item for item in crisis_data
                           if item['data_type'] == 'official']

    if not official_statements:
        transparency_score = 1.5
        return transparency_score

    # 透明度评估指标
    # 有公认的问题
    has_acknowledged_issue = False
    # 解释了原因
    has_explained_cause = False
    # 提出了解决方案
    has_proposed_solution = False
    # 给出了解决问题时间节点
    has_given_timeline = False
    # 承担责任
    has_accepted_responsibility = False

    # 关键词和短语
    acknowledgement_terms = ['承认', '确认', '意识到', '注意到', '收到反馈', '了解到']
    cause_terms = ['原因', '导致', '因为', '由于', '分析']
    solution_terms = ['解决', '修复', '改进', '优化', '更新', '升级', '措施']
    timeline_terms = ['计划', '时间表', '将在', '预计', '天内', '小时内', '即将']
    responsibility_terms = ['责任', '负责', '问题在于我们', '我们的错', '道歉', '抱歉']

    # 检查每个官方声明
    for statement in official_statements:
        content = statement['content']

        # 检查各项指标
        if any(term in content for term in acknowledgement_terms):
            has_acknowledged_issue = True

        if any(term in content for term in cause_terms):
            has_explained_cause = True

        if any(term in content for term in solution_terms):
            has_proposed_solution = True

        if any(term in content for term in timeline_terms):
            has_given_timeline = True

        if any(term in content for term in responsibility_terms):
            has_accepted_responsibility = True

    # 计算透明度得分
    transparency_indicators = [
        has_acknowledged_issue,
        has_explained_cause,
        has_proposed_solution,
        has_given_timeline,
        has_accepted_responsibility
    ]

    # 计算满足的指标数量
    met_indicators = sum(transparency_indicators)

    # 根据满足的指标数量评分
    if met_indicators >= 5:
        score = 5.0  # 完全透明
    elif met_indicators == 4:
        score = 4.0  # 高度透明
    elif met_indicators == 3:
        score = 3.0  # 一般透明
    elif met_indicators == 2:
        score = 2.0  # 较低透明
    else:
        score = 1.0  # 不透明

    transparency_score = score
    return score


def evaluate_brand_image_protection(crisis_data):
    """
    评估品牌形象保护

    Returns:
        品牌形象保护评分 (1-5)
    """
    if not crisis_data:
        return 0

    # 按日期分组计算平均情感得分
    sentiment_by_date = defaultdict(list)

    for item in crisis_data:
        sentiment_by_date[item['date']].append(item['sentiment_score'])

    # 计算每日平均情感得分
    daily_sentiment = {}
    for date, scores in sentiment_by_date.items():
        daily_sentiment[date] = sum(scores) / len(scores)

    # 按时间顺序排列日期
    sorted_dates = sorted(daily_sentiment.keys())

    if len(sorted_dates) < 2:
        image_protection_score = 3
        return image_protection_score

    # 获取危机前、中、后的情感得分
    crisis_start_idx = len(sorted_dates) // 3
    crisis_end_idx = crisis_start_idx * 2

    pre_crisis = sorted_dates[:crisis_start_idx]
    during_crisis = sorted_dates[crisis_start_idx:crisis_end_idx]
    post_crisis = sorted_dates[crisis_end_idx:]

    # 计算各阶段平均情感得分
    pre_sentiment = sum(daily_sentiment[date] for date in pre_crisis) / len(pre_crisis) if pre_crisis else 0
    during_sentiment = sum(daily_sentiment[date] for date in during_crisis) / len(
        during_crisis) if during_crisis else 0
    post_sentiment = sum(daily_sentiment[date] for date in post_crisis) / len(post_crisis) if post_crisis else 0

    # 分析情感变化
    sentiment_drop = pre_sentiment - during_sentiment
    sentiment_recovery = post_sentiment - during_sentiment

    # 评估恢复程度
    recovery_ratio = sentiment_recovery / sentiment_drop if sentiment_drop > 0 else 0

    # 根据恢复程度评分
    if recovery_ratio >= 1.0:
        score = 5.0  # 完全恢复或超越
    elif recovery_ratio >= 0.8:
        score = 4.5  # 接近完全恢复
    elif recovery_ratio >= 0.6:
        score = 4.0  # 显著恢复
    elif recovery_ratio >= 0.4:
        score = 3.5  # 良好恢复
    elif recovery_ratio >= 0.2:
        score = 3.0  # 部分恢复
    elif recovery_ratio > 0:
        score = 2.5  # 轻微恢复
    elif recovery_ratio == 0:
        score = 2.0  # 无恢复
    else:
        score = 1.5  # 持续恶化

    return score


def generate_comprehensive_score(response_speed_score, transparency_score, image_protection_score):
    """
    生成综合评分

    Returns:
        综合评分 (1-5)
    """
    # 确保已评估各项指标
    if response_speed_score == 0:
        evaluate_response_speed()

    if transparency_score == 0:
        evaluate_transparency()

    if image_protection_score == 0:
        evaluate_brand_image_protection()

    # 加权计算综合得分
    score = (
            response_speed_score * 0.3 +
            transparency_score * 0.3 +
            image_protection_score * 0.4
    )

    comprehensive_score = round(score, 1)

    return comprehensive_score


def generate_evaluation_report(response_speed_score, transparency_score, image_protection_score, comprehensive_score):
    """
    生成评估报告


    Returns:
        是否成功生成报告
    """

    try:
        # 生成评估结果
        evaluation_results = [
            {
                "评估项目": "响应速度",
                "评分": response_speed_score,
                "建议": _generate_response_speed_recommendation(response_speed_score)
            },
            {
                "评估项目": "沟通透明度",
                "评分": transparency_score,
                "建议": _generate_transparency_recommendation(transparency_score)
            },
            {
                "评估项目": "品牌形象保护",
                "评分": image_protection_score,
                "建议": _generate_image_protection_recommendation(image_protection_score)
            },
            {
                "评估项目": "综合得分",
                "评分": comprehensive_score,
                "建议": "综合以下各项建议"
            },
            {
                "评估项目": "总体评估",
                "评分": _get_overall_assessment(comprehensive_score),
                "建议": f"特斯拉危机处理整体表现{_get_overall_assessment(comprehensive_score)}，综合得分为{comprehensive_score}分（满分5分）"
            }
        ]

        return evaluation_results

    except Exception as e:
        return False


def _generate_response_speed_recommendation(response_speed_score):
    """生成响应速度建议"""
    if response_speed_score >= 4.5:
        return f"特斯拉响应速度非常快，有效控制了危机扩散"
    elif response_speed_score >= 3.5:
        return f"特斯拉响应速度良好，基本控制了危机扩散，可进一步提高应急机制效率"
    elif response_speed_score >= 2.5:
        return f"特斯拉响应速度一般，对危机控制有一定延迟，建议建立更高效的危机监测和响应流程"
    else:
        return f"特斯拉响应速度较慢，未能及时控制危机扩散，建议全面优化危机响应机制和团队协作流程"


def _generate_transparency_recommendation(transparency_score):
    """生成沟通透明度建议"""
    if transparency_score >= 4.5:
        return f"特斯拉沟通透明度很高，公开了危机详情并积极承担责任，消费者信任度高"
    elif transparency_score >= 3.5:
        return f"特斯拉沟通透明度良好，但可以提供更多危机处理细节和后续改进措施"
    elif transparency_score >= 2.5:
        return f"特斯拉沟通透明度一般，建议增加信息公开程度，主动承认问题并详细说明解决方案"
    else:
        return f"特斯拉沟通透明度不足，建议改变危机沟通策略，增加信息透明度并与用户保持持续沟通"


def _generate_image_protection_recommendation(image_protection_score):
    """生成品牌形象保护建议"""
    if image_protection_score >= 4.5:
        return f"特斯拉形象保护效果极佳，危机后品牌形象不减反增"
    elif image_protection_score >= 3.5:
        return f"特斯拉形象保护效果良好，危机后品牌形象基本恢复"
    elif image_protection_score >= 2.5:
        return f"特斯拉形象保护效果一般，危机对品牌形象造成了一定影响，建议加强后续正面信息传播"
    else:
        return f"特斯拉形象保护效果较差，危机严重损害了品牌形象，建议制定长期品牌形象修复计划"


def _get_overall_assessment(comprehensive_score):
    """获取总体评估结果"""
    if comprehensive_score >= 4.5:
        return "优秀"
    elif comprehensive_score >= 3.5:
        return "良好"
    elif comprehensive_score >= 2.5:
        return "一般"
    elif comprehensive_score >= 1.5:
        return "较差"
    else:
        return "很差"
